package cfile

import (
	"crypto/md5"
	"errors"
	"fileServer/setting"
	"fmt"
	"io"
	"log"
	"os"
	"reflect"
	"strconv"
	"strings"
)

const LevelKB int64 = 1024
const LevelMB int64 = 1024 * 1024
const LevelGB int64 = 1024 * 1024 * 1024

type InfoString struct {
	Sn   string `json:"sn"`
	Name string `json:"name"`
	Path string `json:"path"`
	Size string `json:"size"`
	Time string `json:"time"`
	MD5  string `json:"md5"`
}

func (file *InfoString) FileInfoToString(sn int, parentPath string, info os.FileInfo) {
	file.Sn = strconv.Itoa(sn)
	file.Name = info.Name()
	file.Path = setting.Setting.PrefixURL + parentPath + info.Name()
	if info.IsDir() {
		file.Path = file.Path + "/"
		file.Size = ""
		file.MD5 = ""
	} else {

		if size := info.Size(); size < LevelKB { //if 条件中可以给 变量赋值，再判断
			file.Size = strconv.FormatInt(info.Size(), 10) + "B"
		} else if LevelKB <= size && size < LevelMB {
			file.Size = strconv.FormatFloat(float64(size)/float64(LevelKB), 'f', 2, 64) + "KB"
		} else if LevelMB <= size && size < LevelGB {
			file.Size = strconv.FormatFloat(float64(size)/float64(LevelMB), 'f', 2, 64) + "MB"
		} else {
			file.Size = strconv.FormatFloat(float64(size)/float64(LevelGB), 'f', 2, 64) + "GB"
		}
		file.MD5 = "MD5"

	}
	file.Time = info.ModTime().Format("2006-01-02 15:04:05")

}

func CalcFileMD5(filename string) (string, error) {
	f, err := os.Open(filename) //打开文件
	if nil != err {
		fmt.Println(err)
		return "", err
	}
	defer f.Close()

	md5Handle := md5.New()         //创建 md5 句柄
	_, err = io.Copy(md5Handle, f) //将文件内容拷贝到 md5 句柄中
	if nil != err {
		fmt.Println(err)
		return "", err
	}
	md := md5Handle.Sum(nil)        //计算 MD5 值，返回 []byte
	md5str := fmt.Sprintf("%x", md) //将 []byte 转为 string
	return md5str, nil
}

func SplitUrl(urlPath string) (filePath string, err error) {
	arr := strings.SplitAfterN(urlPath, setting.Setting.PrefixURL, 2)
	if len(arr) == 2 {
		filePath = setting.Setting.DIRPath + arr[1]
	} else {
		// 创建errors类型 实例
		err = errors.New("路径错误")
	}
	// 必须写return 才能返回函数定义的返回值
	return
}

func CheckIsHidden(file os.FileInfo) bool {
	//"通过反射来获取Win32FileAttributeData的FileAttributes
	fa := reflect.ValueOf(file.Sys()).Elem().FieldByName("FileAttributes").Uint()
	bytefa := []byte(strconv.FormatUint(fa, 2))
	if bytefa[len(bytefa)-2] == '1' {
		log.Println("隐藏文件:", file.Name())
		return true
	}
	return false
}
